/*
	Copyright (C) 2011 Salil Bhagurkar

	This file is part of illusion

	illusion is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, either version 3 of
	the License, or (at your option) any later version.

	illusion is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with illusion.
	If not, see <http://www.gnu.org/licenses/>.
*/

#include <klib/lib.h>
#include <kernel/module.h>
#include <kernel/ilapp.h>
#include <kernel/errors.h>
#include <apimod/apimod.h>
#include <kernel/vfs.h>
#include <kernel/input.h>
#include <kernel/ilapp_base.h>
#include <kernel/list.h>

static struct apimod_console *console;
static struct apimod_lib_string *lib_string;
static struct apimod_base *base;
static struct apimod_fs *fs;
static struct apimod_lib_memory *memory;
static struct apimod_ini *ini;

int ilapp_main()
{
	GETI("console", &console);
	GETI("lib_string", &lib_string);
	GETI("base", &base);
	GETI("fs", &fs);
	GETI("memory", &memory);
	GETI("ini", &ini);

	unsigned long len;
	char *args = base->get_arguments(&len);

	unsigned long file;
	int err;

	if(args == null) {
		err = fs->open(".", STATE_READ, &file);
		if(err != 0) {
			console->printf("Failed to open '.'");
			return 0;
		}
	} else {
		err = fs->open(args, STATE_READ, &file);
		if(err != 0) {
			console->printf("Invalid path: %s\n", args);
			return 0;
		}
	}

	struct sys_info info;
	fs->get_info(file, &info);
	if(info.length) {
		char *buf = (char *)memory->malloc(info.length);
		err = fs->read(file, buf, 0, info.length);
		if(err) {
			console->printf("cat: Failed to read from file!\n");
			memory->free(buf, info.length);
		} else {
			//Decode the file data
			struct sys_info1 info1;
			fs->get_info1(file, &info1);
			struct ini_config *conf;
			err = ini->read(&conf, "illusion:/rdisk/catsys.ini");
			if(err) {
				console->print(buf, info.length);
				memory->free(buf, info.length);
				goto cleanup;
			}
			struct ini_class *class;
			list_for(conf->classes, class) {
				if(lib_string->equals(info1.path, class->name)) {
					void *ptr = buf;
					while(ptr < (void *)(buf + info.length)) {
						struct ini_setting *setting;
						list_for(class->settings, setting) {
							if(lib_string->equals(setting->name, "u4")) {
								if(!lib_string->equals(setting->value, "ignore"))
									console->printf("%s = %u\n", setting->value, *(unsigned long *)ptr);
								ptr += 4;
							} else if(lib_string->equals(setting->name, "ptr")) {
								if(!lib_string->equals(setting->value, "ignore"))
									console->printf("%s = 0x%x\n", setting->value, *(unsigned long *)ptr);
								ptr += 4;
							}
						}
					}
					break;
				}
			}
			ini->dispose(conf);

			memory->free(buf, info.length);
		}
	}
	cleanup:

	fs->close(file);

	if(args)
		memory->free(args, len + 1);

	return 0;
}
